home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / DEMOS / REFLECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-14  |  9.0 KB  |  414 lines

  1. /* $Id: reflect.c,v 3.0 1998/02/14 18:42:29 brianp Exp $ */
  2.  
  3. /*
  4.  * Demo of a reflective, texture-mapped surface with OpenGL.
  5.  * Brian Paul   August 14, 1995   This file is in the public domain.
  6.  *
  7.  * Hardware texture mapping is highly recommended!
  8.  *
  9.  * The basic steps are:
  10.  *    1. Render the reflective object (a polygon) from the normal viewpoint,
  11.  *       setting the stencil planes = 1.
  12.  *    2. Render the scene from a special viewpoint:  the viewpoint which
  13.  *       is on the opposite side of the reflective plane.  Only draw where
  14.  *       stencil = 1.  This draws the objects in the reflective surface.
  15.  *    3. Render the scene from the original viewpoint.  This draws the
  16.  *       objects in the normal fashion.  Use blending when drawing
  17.  *       the reflective, textured surface.
  18.  *
  19.  * This is a very crude demo.  It could be much better.
  20.  */
  21.  
  22. /*
  23.  * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
  24.  *
  25.  * August 1996 - A few optimizations by Brian
  26.  */
  27.  
  28. /*
  29.  * April, 1997 - Added Mark Kilgard's changes.
  30.  */
  31.  
  32. /*
  33.  * $Log: reflect.c,v $
  34.  * Revision 3.0  1998/02/14 18:42:29  brianp
  35.  * initial rev
  36.  *
  37.  */
  38.  
  39.  
  40. #define USE_ZBUFFER
  41.  
  42.  
  43. /* OK, without hardware support this is overkill. */
  44. #define USE_TEXTURE
  45.  
  46. #include <math.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include "GL/glut.h"
  50.  
  51. #include "../util/readtex.c"  /* a hack, I know */
  52.  
  53.  
  54. #define DEG2RAD (3.14159/180.0)
  55.  
  56.  
  57. #define TABLE_TEXTURE "reflect.rgb"
  58.  
  59. static int ImgWidth, ImgHeight;
  60. static GLenum ImgFormat;
  61. static GLubyte *Image = NULL;
  62.  
  63. #define MAX_OBJECTS 2
  64.  
  65. static GLint table_list;
  66. static GLint objects_list[MAX_OBJECTS];
  67.  
  68.  
  69. static GLfloat xrot, yrot;
  70. static GLfloat spin;
  71.  
  72.  
  73.  
  74. static void make_table( void )
  75. {
  76.    static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  77.    static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  78.  
  79.    table_list = glGenLists(1);
  80.    glNewList( table_list, GL_COMPILE );
  81.  
  82.    /* load table's texture */
  83.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
  84. /*   glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
  85.    glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
  86.    glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
  87.    
  88.    /* draw textured square for the table */
  89.    glPushMatrix();
  90.    glScalef( 4.0, 4.0, 4.0 );
  91.    glBegin( GL_POLYGON );
  92.    glNormal3f( 0.0, 1.0, 0.0 );
  93.    glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
  94.    glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
  95.    glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
  96.    glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
  97.    glEnd();
  98.    glPopMatrix();
  99.  
  100.    glDisable( GL_TEXTURE_2D );
  101.  
  102.    glEndList();
  103. }
  104.  
  105.  
  106. static void make_objects( void )
  107. {
  108.    GLUquadricObj *q;
  109.  
  110.    static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  111.    static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  112.    static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  113.  
  114.    q = gluNewQuadric();
  115.    gluQuadricDrawStyle( q, GLU_FILL );
  116.    gluQuadricNormals( q, GLU_SMOOTH );
  117.  
  118.    objects_list[0] = glGenLists(1);
  119.    glNewList( objects_list[0], GL_COMPILE );
  120.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  121.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  122.    gluCylinder( q, 0.5, 0.5,  1.0, 15, 10 );
  123.    glEndList();
  124.  
  125.    objects_list[1] = glGenLists(1);
  126.    glNewList( objects_list[1], GL_COMPILE );
  127.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  128.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  129.    gluCylinder( q, 1.5, 0.0,  2.5, 15, 10 );
  130.    glEndList();
  131. }
  132.  
  133.  
  134. static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
  135.  
  136. static void init( void )
  137. {
  138.    make_table();
  139.    make_objects();
  140.  
  141.    /* Setup texture */
  142. #ifdef USE_TEXTURE
  143.  
  144.    Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
  145.    if (!Image) {
  146.       printf("Couldn't read %s\n", TABLE_TEXTURE);
  147.       exit(0);
  148.    }
  149.  
  150.    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight,
  151.                      ImgFormat, GL_UNSIGNED_BYTE, Image);
  152.  
  153.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  154.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  155.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  156.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  157. #endif
  158.  
  159.  
  160.    xrot = 30.0;
  161.    yrot = 50.0;
  162.    spin = 0.0;
  163.  
  164. #ifndef USE_ZBUFFER
  165.    glEnable( GL_CULL_FACE );
  166. #endif
  167.  
  168.    glShadeModel( GL_FLAT );
  169.    
  170.    glEnable( GL_LIGHT0 );
  171.    glEnable( GL_LIGHTING );
  172.  
  173.    glClearColor( 0.5, 0.5, 0.5, 1.0 );
  174.  
  175.    glEnable( GL_NORMALIZE );
  176. }
  177.  
  178.  
  179.  
  180. static void reshape(int w, int h)
  181. {
  182.    GLfloat aspect = (float) w / (float) h;
  183.  
  184.    glViewport(0, 0, w, h);
  185.    glMatrixMode(GL_PROJECTION);
  186.    glLoadIdentity();
  187.    glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
  188.    glMatrixMode(GL_MODELVIEW);
  189.    glLoadIdentity();
  190. }
  191.  
  192.  
  193.  
  194. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  195. {
  196. #ifndef USE_ZBUFFER
  197.     if (eyex<0.5)
  198.     {
  199. #endif
  200.        glPushMatrix();
  201.        glTranslatef( 1.0, 1.5, 0.0 );
  202.        glRotatef( spin, 1.0, 0.5, 0.0 );
  203.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  204.        glCallList( objects_list[0] );
  205.        glPopMatrix();
  206.     
  207.        glPushMatrix();
  208.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  209.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  210.        glRotatef( spin, 1.0, 0.5, 0.0 );
  211.        glScalef( 0.5, 0.5, 0.5 );
  212.        glCallList( objects_list[1] );
  213.        glPopMatrix();
  214. #ifndef USE_ZBUFFER
  215.     }
  216.     else
  217.     {    
  218.        glPushMatrix();
  219.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  220.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  221.        glRotatef( spin, 1.0, 0.5, 0.0 );
  222.        glScalef( 0.5, 0.5, 0.5 );
  223.        glCallList( objects_list[1] );
  224.        glPopMatrix();
  225.  
  226.        glPushMatrix();
  227.        glTranslatef( 1.0, 1.5, 0.0 );
  228.        glRotatef( spin, 1.0, 0.5, 0.0 );
  229.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  230.        glCallList( objects_list[0] );
  231.        glPopMatrix();
  232.     }
  233. #endif
  234. }
  235.  
  236.  
  237.  
  238. static void draw_table( void )
  239. {
  240.    glCallList( table_list );
  241. }
  242.  
  243.  
  244.  
  245. static void draw_scene( void )
  246. {
  247.    GLfloat dist = 20.0;
  248.    GLfloat eyex, eyey, eyez;
  249.  
  250.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  251.  
  252.  
  253.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  254.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  255.    eyey = dist * sin(xrot*DEG2RAD);
  256.  
  257.    /* view from top */
  258.    glPushMatrix();
  259.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  260.  
  261.    glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  262.  
  263.    /* draw table into stencil planes */
  264.    glEnable( GL_STENCIL_TEST );
  265. #ifdef USE_ZBUFFER
  266.    glDisable( GL_DEPTH_TEST );
  267. #endif
  268.    glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  269.    glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  270.    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  271.    draw_table();
  272.    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  273.  
  274. #ifdef USE_ZBUFFER
  275.    glEnable( GL_DEPTH_TEST );
  276. #endif
  277.  
  278.  
  279.    /* render view from below (reflected viewport) */
  280.    /* only draw where stencil==1 */
  281.    if (eyey>0.0) {
  282.       glPushMatrix();
  283.  
  284.       glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
  285.       glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  286.       glScalef( 1.0, -1.0, 1.0 );
  287.  
  288.       /* Reposition light in reflected space. */
  289.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  290.  
  291.       draw_objects(eyex, eyey, eyez);
  292.       glPopMatrix();
  293.  
  294.       /* Restore light's original unreflected position. */
  295.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  296.    }
  297.  
  298.    glDisable( GL_STENCIL_TEST );
  299.  
  300.    glEnable( GL_BLEND );
  301.    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  302.  
  303. #ifdef USE_TEXTURE
  304.    glEnable( GL_TEXTURE_2D );
  305. #endif
  306.    draw_table();
  307.    glDisable( GL_TEXTURE_2D );
  308.    glDisable( GL_BLEND );
  309.  
  310.    /* view from top */
  311.    glPushMatrix();
  312.  
  313.    draw_objects(eyex, eyey, eyez);
  314.  
  315.    glPopMatrix();
  316.  
  317.    glPopMatrix();
  318.  
  319.    glutSwapBuffers();
  320. }
  321.  
  322.  
  323.  
  324. #if 0
  325. void draw_scene(void)
  326. {
  327.    GLfloat dist = 20.0;
  328.    GLfloat eyex, eyey, eyez;
  329.  
  330.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  331.  
  332.  
  333.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  334.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  335.    eyey = dist * sin(xrot*DEG2RAD);
  336.  
  337.    /* view from top */
  338.    glPushMatrix();
  339.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  340.  
  341.    draw_table();
  342.  
  343.    glPopMatrix();
  344.  
  345.    glutSwapBuffers();
  346. }
  347. #endif
  348.  
  349.  
  350. static void Key( unsigned char key, int x, int y )
  351. {
  352.    if (key==27)
  353.       exit(0);
  354. }
  355.  
  356.  
  357. static void SpecialKey( int key, int x, int y )
  358. {
  359.    switch (key) {
  360.       case GLUT_KEY_UP:
  361.          xrot += 3.0;
  362. #ifndef USE_ZBUFFER
  363.          if ( xrot > 180 )    xrot = 180;
  364. #endif
  365.          break;
  366.       case GLUT_KEY_DOWN:
  367.          xrot -= 3.0;
  368. #ifndef USE_ZBUFFER
  369.          if ( xrot < 0 )    xrot = 0;
  370. #endif
  371.          break;
  372.       case GLUT_KEY_LEFT:
  373.          yrot += 3.0;
  374.          break;
  375.       case GLUT_KEY_RIGHT:
  376.          yrot -= 3.0;
  377.          break;
  378.    }
  379.    glutPostRedisplay();
  380. }
  381.  
  382.  
  383.  
  384. static void idle( void )
  385. {
  386.    spin += 2.0;
  387.    yrot += 3.0;
  388.    glutPostRedisplay();
  389. }
  390.  
  391.  
  392.  
  393. int main( int argc, char *argv[] )
  394. {
  395.    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB 
  396. #ifdef USE_ZBUFFER
  397.         | GLUT_DEPTH 
  398. #endif
  399.         | GLUT_STENCIL);
  400.    glutInitWindowPosition( 0, 0 );
  401.    glutInitWindowSize(400, 300 );
  402.    glutCreateWindow(argv[0]);
  403.    glutReshapeFunc(reshape);
  404.    glutDisplayFunc(draw_scene);
  405.    glutKeyboardFunc(Key);
  406.    glutSpecialFunc(SpecialKey);
  407.    glutIdleFunc(idle);
  408.  
  409.    init();
  410.  
  411.    glutMainLoop();
  412.    return 0;
  413. }
  414.